﻿using Publicuse.Entity.AttributeUtil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Util
{
    /// <summary>
    /// 表名字段属性
    /// </summary>
    public static class TableColumnAttribute
    {
        public static string GetMappingName<T>(this T t) where T : MemberInfo
        {
            if (t.IsDefined(typeof(BaseMappingAttribute), true))
            {
                var attribute = t.GetCustomAttribute<BaseMappingAttribute>();
                return attribute.GetMappingName();
            }
            else
            {
                return t.Name;
            }
        }
    }

    /// <summary>
    /// 属性基类
    /// </summary>
    public class BaseMappingAttribute : Attribute
    {
        private string _MappingName = null;
        public BaseMappingAttribute(string mappingName)
        {
            this._MappingName = mappingName;
        }
        public string GetMappingName()
        {
            return this._MappingName;
        }
    }

    /// <summary>
    /// 过滤不是新增和修改和获取主键的字段扩展类
    /// </summary>
    public static class DBFilterExtend
    {
        /// <summary>
        /// 过滤不是新增的字段
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithNoInsert(this Type type)
        {
            return type.GetProperties().Where(p => !p.IsDefined(typeof(NoInsertAttribute), true));
        }

        /// <summary>
        /// 过滤不是修改的字段
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithNoUpdate(this Type type)
        {
            return type.GetProperties().Where(p => !p.IsDefined(typeof(NoUpdateAttribute), true));
        }

        /// <summary>
        /// 过滤不是查询的字段
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithNoQuery(this Type type)
        {
            return type.GetProperties().Where(p => !p.IsDefined(typeof(NoQueryAttribute), true));
        }

        /// <summary>
        /// 获取编号集合查询条件
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesIdsQuery(this Type type)
        {
            return type.GetProperties().Where(p => p.IsDefined(typeof(ExportidsAttribute), true));
        }

        /// <summary>
        /// 交通数据管理模块是年度类型字段区分20220314
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithYearcom(this Type type)
        {
            return type.GetProperties().Where(p => p.IsDefined(typeof(YearcomAttribute), true));
        }

        /// <summary>
        /// 交通数据管理模块不是是年度类型字段区分20220314
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithNoYearcom(this Type type)
        {
            return type.GetProperties().Where(p => p.IsDefined(typeof(NoYearcomAttribute), true));
        }
        /// <summary>
        /// 获取额外查询的字段
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithCombinationQuery(this Type type)
        {
            return type.GetProperties().Where(p => p.IsDefined(typeof(CombinationQueryAttribute), true));
        }

        /// <summary>
        /// 获取主键
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesWithKey(this Type type)
        {
            return type.GetProperties().Where(p => p.IsDefined(typeof(PrimaryKeyAttribute), true));
        }

        /// <summary>
        /// 就是通过json字符串找出更新的字段
        /// </summary>
        /// <param name="type"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static IEnumerable<PropertyInfo> GetPropertiesInJson(this Type type, string json)
        {
            return type.GetProperties().Where(p => json.Contains($"'{p.Name}':") || json.Contains($"\"{p.Name}\":"));
        }

        /// <summary>
        /// 根据字段类型返回值
        /// </summary>
        /// <param name="pi"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static object GetValue(this string data, PropertyInfo pi)
        {
            object backdata = null;
            switch (pi.PropertyType.FullName)
            {
                case "System.Double":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = Convert.ToDouble(data);
                    break;
                case "System.Int64":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = Convert.ToInt64(data);
                    break;
                case "System.Int32":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = Convert.ToInt32(data);
                    break;
                case "System.Float":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = Convert.ToDouble(data);
                    break;
                case "System.DateTime":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = Convert.ToDateTime(data);
                    break;
                case "System.TimeSpan":
                    if (string.IsNullOrEmpty(data))
                        backdata = 0;
                    else
                        backdata = TimeSpan.Parse(data);
                    break;
                default:
                    backdata = data;
                    break;
            }
            if (pi.PropertyType.FullName.Contains("System.DateTime"))
            {
                backdata = Convert.ToDateTime(data);
            }
            return backdata;
        }
    }
}
